package com.miyake.dsp.osa;

import java.util.LinkedList;
import java.util.List;

import org.apache.commons.lang.ArrayUtils;

import com.miyake.dsp.ComplexArray;
import com.miyake.dsp.common.UnitConverter;
import com.miyake.dsp.fitting.FittingScilab;
import com.miyake.dsp.fitting.FittingSetting;
import com.miyake.dsp.ui.LineChartPanel;

public class OneFit {

	double[] inFit;
	double[] outFit;
	double[] wavelengthFit;
	
	public void analyze(int[] peaks, double[] wavelength, double[] in, double[] out, AnalysisProperty anaProp) {
		List<Double> waveList = new LinkedList<Double>();
		List<Double> inList = new LinkedList<Double>();
		List<Double> outList = new LinkedList<Double>();
		
		for (int i = 0; i < peaks.length; i++) {
			int peakIndex = peaks[i];

			int fittingStart = peakIndex - toSpanIndex(wavelength, anaProp.getFittingSpan() / 2.0);
			int fittingEnd = peakIndex + toSpanIndex(wavelength, anaProp.getFittingSpan() / 2.0);
			int maskedStart = peakIndex - toSpanIndex(wavelength, anaProp.getMaskedSpan() / 2.0);
			int maskedEnd = peakIndex + toSpanIndex(wavelength, anaProp.getMaskedSpan() / 2.0);
			
			for (int j = fittingStart; j < fittingEnd; j++) {
				if (j < maskedStart || j > maskedEnd) {
					waveList.add(wavelength[j]);
					inList.add(in[j]);
					outList.add(out[j]);
				}
			}
		}
		
		Double[] waveArray = waveList.toArray(new Double[0]);
		Double[] inArray = inList.toArray(new Double[0]);
		Double[] outArray = outList.toArray(new Double[0]);
		
		FittingSetting setting = new FittingSetting(anaProp.getFormula(), 
				0, waveArray.length-1, in.length);

		FittingScilab fitting = new FittingScilab(setting);
		fitting.setSource(new ComplexArray(ArrayUtils.toPrimitive(inArray)));
		inFit = fitting.getProcessed().getRealPart();
		
		fitting.setSource(new ComplexArray(ArrayUtils.toPrimitive(outArray)));
		outFit = fitting.getProcessed().getRealPart();
		
		wavelengthFit = ArrayUtils.toPrimitive(waveArray);
		
		LineChartPanel chart = LineChartPanel.createChart();
		if (isLog()) {
			chart.setData("in", wavelength, UnitConverter.todBm(in));
			chart.setData("out", wavelength, UnitConverter.todBm(out));
			chart.setData("in-fit", wavelengthFit, UnitConverter.todBm(inFit));
			chart.setData("out-fit", wavelengthFit, UnitConverter.todBm(outFit));
		}
		
		else {
			chart.setData("in", wavelength, in);
			chart.setData("out", wavelength, out);
			chart.setData("in-fit", wavelengthFit, inFit);
			chart.setData("out-fit", wavelengthFit, outFit);
		}
	}

	private boolean isLog() {
		return true;
	}

	private int toSpanIndex(double[] wavelength, double d) {
		double step = (wavelength[wavelength.length-1] - wavelength[0]) / (double)(wavelength.length-1);
		return (int) (d / step);
	}

	public double[] getInFit() {
		return inFit;
	}

	public double[] getOutFit() {
		return outFit;
	}

	public double[] getWavelengthFit() {
		return wavelengthFit;
	}
	
	
}
